from flask import request, make_response, jsonify, Flask, abort

from future_fields import FutureField

from analyse import Analyse

app:Flask = FutureField("app").get()
analyse:Analyse = FutureField("analyse")

def make_meta():
    meta = {
        "max_task": app.task_manager.max_task,
        "active_task_count": app.task_manager.active_task_count
    }
    return meta

def check_arguments_valid(kwargs):
    """
    根据要求检查request 参数是否合法
    kwargs:
    {
        "id": int, str # int,str 代表要求类型
    }
    """
    args = request.json
    result = {
        "bad_arguments":{}    
    }

    for d in kwargs.items():
        key = d[0]
        arg_types = d[1:]
        value = args.get(key)
        if not value: 
            result["bad_arguments"][key] = "missing"
        else:
            t = type(value)
            if t not in arg_types: result["bad_arguments"][key] = "wrong_type"

    result["valid"] = not len(result["bad_arguments"].keys())
    return result

@app.route("/", methods=["GET"])
def index():
    """
    获取元数据。
    """
    code = 200
    msg = "success"

    return jsonify(code=code, msg=msg, data = make_meta())

@app.route("/task/new/", methods=["POST"])
def task_new():
    """
    创建新的分割任务。
    """
    data = {}
    valid = check_arguments_valid({
        "id": int,
        "text": str
    })
    if not valid["valid"]: # 缺参数/类型不对
        data["code"] = 400
        data["msg"] = "bad_request"
        data["bad_arguments"] = valid["bad_arguments"]
        return jsonify(data)
    # 创建任务并返回结果
    id = request.json.get("id")
    status = app.task_manager.add_task(id, analyse.get().get)
    if status == "too_many_task": # 任务过多
        data["code"] = 503
        data["msg"] = "service_unavailable"
        data["hint"] = "too many task"
        return jsonify(data)
    if status == "task_exists": # 对应id任务存在, 没有完成或者取出结果
        data["code"] = 406
        data["msg"] = "not_acceptable"
        data["hint"] = "The specific task already exists"
        return jsonify(data)
    # 成功，运行
    text = request.json.get("text")
    app.task_manager.run_task(id, args=(text,))
    data["code"] = 200
    data["msg"] = "success"
    data["hint"] = "task running, GET /task/<id:int>/ to get result"
    return jsonify(data)

@app.route("/task/<int:id>/", methods=["GET"])
def task_get(id:int):
    data = {}
    data["code"] = 200
    data["msg"] = "success"
    status = data["status"] = app.task_manager.check_status(id)
    if status == "not_found": abort(404)

    if status == "end": # 结束
        data["data"] = app.task_manager.get_result(id)[1]
        app.task_manager.clean_task(id)   
    if  status == "error":
        print(app.task_manager.get_error(id)[1]) 
        app.task_manager.clean_task(id)    

    return jsonify(data)